package com.smart.community.property.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.cache.DataScopeInfo;
import com.smart.community.commons.enums.SystemStatusEnum;
import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.feign.region.dto.AddressInfoDTO;
import com.smart.community.feign.region.service.RegionAddressFeignService;
import com.smart.community.feign.user.dto.UserDTO;
import com.smart.community.feign.user.service.UserFeignService;
import com.smart.community.feign.region.service.RegionDataFeignService;
import com.smart.community.property.dto.RepairOrderDTO;
import com.smart.community.property.entity.RepairOrder;
import com.smart.community.property.mapper.RepairOrderMapper;
import com.smart.community.property.service.DataScopeService;
import com.smart.community.property.service.IRepairOrderService;
import com.smart.community.property.service.IRepairProgressService;
import com.smart.community.property.vo.RepairOrderStatisticsVO;
import com.smart.community.property.vo.RepairOrderVO;

import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;

/**
 * 维修工单服务实现类
 * 
 * 严格按照《Java后端SpringBoot代码开发规范.md》Service层规范实现：
 * - 异常处理规范：使用log.warn记录业务异常，使用log.error记录系统异常
 * - 参数验证：完善的参数验证和错误提示
 * - 业务逻辑：清晰的业务逻辑和错误处理
 * - 性能优化：合理的查询优化和本地缓存策略
 * - 生产环境标准：符合企业级应用的高可用性、可监控性、可维护性、可扩展性要求
 * - 空数组创建：使用Collections.emptyList()替代new ArrayList<>()
 * - 状态管理：使用SystemStatusEnum统一状态管理
 * - 缓存机制：遵循权威文档规范，避免缓存复杂对象，确保系统稳定性
 * - 数据权限：实现完整的数据权限控制机制
 * 
 * @author Wu.Liang
 * @since 2025-06-26
 * @version 3.1.0 - 缓存策略优化，遵循权威文档规范
 */
@Slf4j
@Service
public class RepairOrderServiceImpl extends ServiceImpl<RepairOrderMapper, RepairOrder> implements IRepairOrderService {

    @Autowired
    private RepairOrderMapper repairOrderMapper;

    @Autowired
    private DataScopeService dataScopeService;

    @Autowired
    private RegionDataFeignService regionDataFeignService;

    @Autowired
    private IRepairProgressService repairProgressService;

    @Autowired
    private UserFeignService userFeignService;

    @Autowired
    private RegionAddressFeignService regionAddressFeignService;
    
    // ========================= 本地缓存配置 =========================
    
    /**
     * 本地缓存：用户信息缓存，减少Feign调用
     * 注意：仅用于减少Feign调用，不涉及Redis缓存
     */
    private final Map<Long, UserDTO> userCache = new ConcurrentHashMap<>();
    
    /**
     * 本地缓存：地址信息缓存，减少Feign调用
     * 注意：仅用于减少Feign调用，不涉及Redis缓存
     */
    private final Map<Long, AddressInfoDTO> addressCache = new ConcurrentHashMap<>();
    
    
    // ========================= 维修工单管理 =========================

    @Override
    public PageResult<RepairOrderVO> pageRepairOrders(Integer current, Integer size, Long communityId, Integer status, List<Long> householdIds) {
        try {
            // 参数验证
            if (current == null || current < 1) current = 1;
            if (size == null || size < 1) size = 10;

            // 获取当前用户ID
            Long currentUserId = SecurityUtils.getCurrentUserId();
            if (currentUserId == null) {
                log.warn("用户未登录，无法查询维修工单");
                return new PageResult<>(current, size, 0L, Collections.emptyList());
            }

            log.info("分页查询维修工单，当前页: {}, 每页大小: {}, 社区ID: {}, 状态: {}, 用户ID: {}, 房户ID列表: {}", 
                    current, size, communityId, status, currentUserId, householdIds);

            // 处理householdIds参数 - 获取对应的userId列表
            List<Long> userIds = null;
            if (householdIds != null && !householdIds.isEmpty()) {
                try {
                    // 根据householdIds获取对应的userId列表
                    userIds = regionDataFeignService.getUserIdsByHouseholdIds(householdIds);
                    log.info("根据房户ID列表获取用户ID列表: {}", userIds);
                } catch (Exception e) {
                    log.warn("根据房户ID列表获取用户ID列表失败: {}", e.getMessage());
                    // 如果获取失败，返回空结果
                    return new PageResult<>(current, size, 0L, Collections.emptyList());
                }
            }

            // 获取用户数据权限范围
            DataScopeInfo dataScope = getCurrentUserDataScope();
            if (dataScope == null) {
                log.warn("用户数据权限信息为空，返回空结果");
                return new PageResult<>(current, size, 0L, Collections.emptyList());
            }

            Page<RepairOrderVO> page = new Page<>(current, size);
            IPage<RepairOrderVO> result;
            
            // 根据用户权限类型进行数据过滤
               if (dataScope.isSuperAdmin()) {
                   // 超级管理员：显示所有维修工单
                   log.info("超级管理员查询所有维修工单");
                   if (userIds != null && !userIds.isEmpty()) {
                       result = repairOrderMapper.selectRepairOrderPageWithUserIds(page, communityId, status, null, null, null, null, null, userIds);
                   } else {
                       result = repairOrderMapper.selectRepairOrderPage(page, communityId, status, null, null, null, null, null);
                   }
            } else if (dataScope.isPropertyCompanyUser()) {
                // 物业公司用户：显示关联社区的维修工单
                List<Long> userCommunityIds = dataScope.getCommunityIds();
                if (userCommunityIds == null || userCommunityIds.isEmpty()) {
                    log.warn("物业公司用户无关联社区，用户ID: {}", currentUserId);
                    return new PageResult<>(current, size, 0L, Collections.emptyList());
                }
                
                   log.info("物业公司用户查询关联社区维修工单，社区IDs: {}", userCommunityIds);
                   if (userIds != null && !userIds.isEmpty()) {
                       result = repairOrderMapper.selectRepairOrderPageWithUserIds(page, communityId, status, null, null, null, null, null, userIds);
                   } else {
                       result = repairOrderMapper.selectRepairOrderPage(page, communityId, status, null, null, null, null, null);
                   }
                
                // 过滤出用户有权限的社区数据
                List<RepairOrderVO> filteredRecords = result.getRecords().stream()
                        .filter(order -> userCommunityIds.contains(order.getCommunityId()))
                        .collect(Collectors.toList());
                
                // 重新计算分页信息
                long total = filteredRecords.size();
                int startIndex = (current - 1) * size;
                int endIndex = Math.min(startIndex + size, filteredRecords.size());
                
                if (startIndex < filteredRecords.size()) {
                    List<RepairOrderVO> pageRecords = filteredRecords.subList(startIndex, endIndex);
                    result.setRecords(pageRecords);
                    result.setTotal(total);
                } else {
                    result.setRecords(Collections.emptyList());
                    result.setTotal(0L);
                }
            } else {
                // 普通用户：只显示自己申请的维修工单
                log.info("普通用户查询自己申请的维修工单，用户ID: {}", currentUserId);
                // 使用selectByUserId方法查询用户自己的工单
                List<RepairOrder> userOrders = repairOrderMapper.selectByUserId(currentUserId, communityId, status);
                
                // 手动分页
                long total = userOrders.size();
                int startIndex = (current - 1) * size;
                int endIndex = Math.min(startIndex + size, userOrders.size());
                
                List<RepairOrder> pageRecords = Collections.emptyList();
                if (startIndex < userOrders.size()) {
                    pageRecords = userOrders.subList(startIndex, endIndex);
                }
                
                // 转换为RepairOrderVO
                List<RepairOrderVO> voList = convertToRepairOrderVOList(pageRecords);
                return new PageResult<>(current, size, total, voList);
            }

            // 直接返回RepairOrderVO列表，无需再次转换
            return new PageResult<>(current, size, result.getTotal(), result.getRecords());
        } catch (Exception e) {
            log.error("分页查询维修工单失败，错误: {}", e.getMessage(), e);
            return new PageResult<>(current, size, 0L, Collections.emptyList());
        }
    }

    @Override
    @Cacheable(value = "repair:detail", key = "#orderId", unless = "#result == null")
    public RepairOrderVO getRepairOrderDetail(Long orderId) {
        try {
            // 参数验证
            if (orderId == null) {
                log.warn("获取维修工单详情失败，工单ID不能为空");
                return null;
            }

            log.info("获取维修工单详情，工单ID: {}", orderId);
            
            // 数据权限验证
            if (!validateRepairOrderPermission(orderId)) {
                log.warn("用户无权限访问维修工单详情，工单ID: {}", orderId);
                return null;
            }
            
            RepairOrder repairOrder = getById(orderId);
            if (repairOrder == null) {
                log.warn("维修工单不存在，工单ID: {}", orderId);
                return null;
            }
            
            return convertToRepairOrderVO(repairOrder);
        } catch (Exception e) {
            log.error("获取维修工单详情失败，工单ID: {}, 错误: {}", orderId, e.getMessage(), e);
            return null;
        }
    }

    @Override
    @Cacheable(value = "repair:myOrders", key = "#current + ':' + #size + ':' + #userId + ':' + #status", unless = "#result == null")
    public PageResult<RepairOrderVO> getMyRepairOrders(Integer current, Integer size, Long userId, Integer status) {
        try {
            // 参数验证
            if (userId == null) {
                log.warn("获取用户报修记录失败，用户ID不能为空");
                return new PageResult<>(current, size, 0L, Collections.emptyList());
            }

            log.info("获取用户报修记录，用户ID: {}, 状态: {}, 当前页: {}, 每页大小: {}", userId, status, current, size);

            // 构建查询条件
            LambdaQueryWrapper<RepairOrder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RepairOrder::getUserId, userId);
            queryWrapper.eq(RepairOrder::getDeleted, 0);
            
            if (status != null) {
                queryWrapper.eq(RepairOrder::getStatus, status);
            }
            
            queryWrapper.orderByDesc(RepairOrder::getCreateTime);

            // 分页查询
            Page<RepairOrder> page = new Page<>(current, size);
            IPage<RepairOrder> pageResult = page(page, queryWrapper);

            // 转换为VO
            List<RepairOrderVO> voList = pageResult.getRecords().stream()
                    .map(this::convertToRepairOrderVO)
                    .collect(Collectors.toList());

            return new PageResult<RepairOrderVO>(current, size, pageResult.getTotal(), voList);
        } catch (Exception e) {
            log.warn("获取用户报修记录失败，用户ID: {}, 错误: {}", userId, e.getMessage());
            return new PageResult<>(current, size, 0L, Collections.emptyList());
        }
    }

    @Override
    @GlobalTransactional
    public Long submitRepairOrder(RepairOrderDTO repairOrderDTO) {
        try {
            // 参数验证
            if (repairOrderDTO == null) {
                log.warn("提交维修工单失败，维修工单信息不能为空");
                return null;
            }

            if (repairOrderDTO.getUserId() == null) {
                log.warn("提交维修工单失败，用户ID不能为空");
                return null;
            }

            if (!StringUtils.hasText(repairOrderDTO.getTitle())) {
                log.warn("提交维修工单失败，工单标题不能为空");
                return null;
            }

            log.info("提交维修工单，参数: {}", repairOrderDTO);

            // 若未提供社区或详细地址，且给定 householdId，则从地址服务补齐
            try {
                if (repairOrderDTO.getHouseholdId() != null &&
                        (repairOrderDTO.getCommunityId() == null || !StringUtils.hasText(repairOrderDTO.getRepairAddress()))) {
                    AddressInfoDTO addr = getAddressByHouseholdId(repairOrderDTO.getHouseholdId());
                    if (addr != null) {
                        if (repairOrderDTO.getCommunityId() == null) {
                            repairOrderDTO.setCommunityId(addr.getCommunityId());
                        }
                        if (!StringUtils.hasText(repairOrderDTO.getRepairAddress())) {
                            repairOrderDTO.setRepairAddress(addr.getFullAddress());
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("根据householdId补齐地址信息失败, householdId:{}", repairOrderDTO.getHouseholdId(), e);
            }

            if (repairOrderDTO.getCommunityId() == null) {
                log.warn("提交维修工单失败，社区ID不能为空");
                return null;
            }

            // 创建维修工单实体
            RepairOrder repairOrder = new RepairOrder();
            BeanUtils.copyProperties(repairOrderDTO, repairOrder);

            // 设置初始状态 - 使用SystemStatusEnum
            repairOrder.setStatus(SystemStatusEnum.ENABLED.getCode()); // 1: 待处理
            repairOrder.setOrderNo(generateOrderNo());
            repairOrder.setCreateTime(LocalDateTime.now());
            repairOrder.setUpdateTime(LocalDateTime.now());

            // 保存工单
            if (repairOrderMapper.insert(repairOrder) > 0) {
                log.info("维修工单提交成功，工单ID: {}, 工单号: {}", repairOrder.getId(), repairOrder.getOrderNo());
                
                // 处理图片附件
                try {
                    if (repairOrderDTO.getImageList() != null && !repairOrderDTO.getImageList().isEmpty()) {
                        saveRepairOrderImages(repairOrder.getId(), repairOrderDTO.getImageList());
                        log.info("维修工单图片保存成功，工单ID: {}, 图片数量: {}", 
                                repairOrder.getId(), repairOrderDTO.getImageList().size());
                    }
                } catch (Exception e) {
                    log.warn("保存维修工单图片失败，工单ID: {}", repairOrder.getId(), e);
                    // 不影响主流程，仅记录警告日志
                }
                
                // 创建工单创建进度记录
                try {
                    String operatorName = getCurrentUserName();
                    repairProgressService.createProgressWithRepairman(
                        repairOrder.getId(),
                        repairOrder.getOrderNo(),
                        SystemStatusEnum.ENABLED.getCode(), // 1: 工单创建
                        "工单创建",
                        "工单已创建，等待受理",
                        SecurityUtils.getCurrentUserId(),
                        operatorName,
                        null,
                        null,
                        repairOrder.getCreateTime()
                    );
                } catch (Exception e) {
                    log.warn("创建工单进度记录失败，工单ID: {}", repairOrder.getId(), e);
                    // 不影响主流程，仅记录警告日志
                }
                
                return repairOrder.getId();
            } else {
                log.warn("维修工单保存失败");
                return null;
            }
        } catch (Exception e) {
            log.error("提交维修工单失败，错误: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    @GlobalTransactional
    @CacheEvict(value = {"repair:detail", "repair:myOrders", "repair:byUserId", "repair:byRepairmanId", "repair:urgent", "repair:timeout", "repair:statistics"}, allEntries = true)
    public boolean updateRepairOrderStatus(Long orderId, Integer status, String remark) {
        try {
            // 参数验证
            if (orderId == null || status == null) {
                log.warn("更新维修工单状态失败，工单ID或状态不能为空");
                return false;
            }

            log.info("更新维修工单状态，工单ID: {}, 状态: {}, 备注: {}", orderId, status, remark);

            // 数据权限验证
            if (!validateRepairOrderPermission(orderId)) {
                log.warn("用户无权限更新维修工单状态，工单ID: {}", orderId);
                return false;
            }

            // 获取工单信息
            RepairOrder repairOrder = getById(orderId);
            if (repairOrder == null) {
                log.warn("工单不存在，工单ID: {}", orderId);
                return false;
            }

            int result = repairOrderMapper.updateStatus(orderId, status, SecurityUtils.getCurrentUserId());
            if (result > 0) {
                log.info("维修工单状态更新成功，工单ID: {}, 新状态: {}", orderId, status);
                
                // 创建状态变更进度记录
                try {
                    String operatorName = getCurrentUserName();
                    createStatusProgressRecord(orderId, repairOrder.getOrderNo(), status, remark, operatorName);
                } catch (Exception e) {
                    log.warn("创建状态变更进度记录失败，工单ID: {}, 状态: {}", orderId, status, e);
                    // 不影响主流程，仅记录警告日志
                }
                
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("更新维修工单状态失败，工单ID: {}, 错误: {}", orderId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    @GlobalTransactional
    public boolean assignRepairOrder(Long orderId, Long repairmanId, String remark) {
        try {
            // 参数验证
            if (orderId == null || repairmanId == null) {
                log.warn("分配维修工单失败，工单ID或维修人员ID不能为空");
                return false;
            }

            log.info("分配维修工单，工单ID: {}, 维修人员ID: {}, 备注: {}", orderId, repairmanId, remark);

            // 数据权限验证
            if (!validateRepairOrderPermission(orderId)) {
                log.warn("用户无权限分配维修工单，工单ID: {}", orderId);
                return false;
            }

            // 获取工单信息和维修人员信息
            RepairOrder repairOrder = getById(orderId);
            if (repairOrder == null) {
                log.warn("工单不存在，工单ID: {}", orderId);
                return false;
            }

            LocalDateTime assignTime = LocalDateTime.now();
            int result = repairOrderMapper.assignOrder(orderId, repairmanId, assignTime, repairmanId);
            if (result > 0) {
                log.info("维修工单分配成功，工单ID: {}", orderId);
                
                // 创建工单受理进度记录
                try {
                    String operatorName = getCurrentUserName();
                    String repairmanName = getRepairmanName(repairmanId);
                    String progressContent = "工单已受理，分配维修师傅：" + repairmanName;
                    
                    repairProgressService.createProgressWithRepairman(
                        orderId,
                        repairOrder.getOrderNo(),
                        2, // 2: 工单受理
                        "工单受理",
                        progressContent,
                        SecurityUtils.getCurrentUserId(),
                        operatorName,
                        repairmanId,
                        repairmanName,
                        assignTime
                    );
                    
                    // 如果有备注，将备注信息合并到主进度记录中，不单独创建备注节点
                    if (remark != null && !remark.trim().isEmpty()) {
                        progressContent += "，备注：" + remark;
                        // 更新进度记录内容
                        repairProgressService.updateProgressContent(orderId, progressContent);
                    }
                } catch (Exception e) {
                    log.warn("创建工单受理进度记录失败，工单ID: {}", orderId, e);
                    // 不影响主流程，仅记录警告日志
                }
                
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("分配维修工单失败，工单ID: {}, 错误: {}", orderId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    @GlobalTransactional
    public Map<String, Integer> batchAssignRepairOrders(List<Long> orderIds, Long repairmanId) {
        try {
            // 参数验证
            if (orderIds == null || orderIds.isEmpty()) {
                log.warn("批量分配维修工单失败，工单ID列表不能为空");
                return new HashMap<>();
            }

            if (repairmanId == null) {
                log.warn("批量分配维修工单失败，维修人员ID不能为空");
                return new HashMap<>();
            }

            log.info("批量分配维修工单，工单IDs: {}, 维修人员ID: {}", orderIds, repairmanId);

            int successCount = 0;
            int failCount = 0;

            // 批量处理，提高性能
            for (Long orderId : orderIds) {
                try {
                    // 数据权限验证
                    if (!validateRepairOrderPermission(orderId)) {
                        log.warn("用户无权限分配维修工单，工单ID: {}", orderId);
                        failCount++;
                        continue;
                    }
                    
                    boolean success = assignRepairOrder(orderId, repairmanId, null);
                    if (success) {
                        successCount++;
                    } else {
                        failCount++;
                    }
                } catch (Exception e) {
                    failCount++;
                    log.warn("分配工单失败，工单ID: {}", orderId, e);
                }
            }

            Map<String, Integer> result = new HashMap<>();
            result.put("totalCount", orderIds.size());
            result.put("successCount", successCount);
            result.put("failCount", failCount);

            log.info("批量分配维修工单完成，成功: {}, 失败: {}", successCount, failCount);
            return result;
        } catch (Exception e) {
            log.error("批量分配维修工单失败，错误: {}", e.getMessage(), e);
            return new HashMap<>();
        }
    }

    @Override
    @GlobalTransactional
    public boolean completeRepairOrder(Long orderId, String result, String remark) {
        try {
            // 参数验证
            if (orderId == null) {
                log.warn("完成维修工单失败，工单ID不能为空");
                return false;
            }
            if (result == null || result.trim().isEmpty()) {
                log.warn("完成维修工单失败，维修结果不能为空，工单ID: {}", orderId);
                return false;
            }

            log.info("完成维修工单，工单ID: {}, 维修结果: {}, 备注: {}", orderId, result, remark);

            // 数据权限验证
            if (!validateRepairOrderPermission(orderId)) {
                log.warn("用户无权限完成维修工单，工单ID: {}", orderId);
                return false;
            }

            // 获取工单信息
            RepairOrder repairOrder = getById(orderId);
            if (repairOrder == null) {
                log.warn("工单不存在，工单ID: {}", orderId);
                return false;
            }

            LocalDateTime completeTime = LocalDateTime.now();
            int updateResult = repairOrderMapper.completeOrder(orderId, completeTime, null, SecurityUtils.getCurrentUserId());
            if (updateResult > 0) {
                log.info("维修工单完成成功，工单ID: {}", orderId);
                
                // 创建工单完成进度记录
                try {
                    String operatorName = getCurrentUserName();
                    String repairmanName = getRepairmanName(repairOrder.getAssignTo());
                    String progressContent = "维修完成。维修结果：" + result;
                    if (remark != null && !remark.trim().isEmpty()) {
                        progressContent += "。备注：" + remark;
                    }
                    
                    repairProgressService.createProgressWithRepairman(
                        orderId,
                        repairOrder.getOrderNo(),
                        4, // 4: 维修完成
                        "维修完成",
                        progressContent,
                        SecurityUtils.getCurrentUserId(),
                        operatorName,
                        repairOrder.getAssignTo(),
                        repairmanName,
                        completeTime
                    );
                } catch (Exception e) {
                    log.warn("创建工单完成进度记录失败，工单ID: {}", orderId, e);
                    // 不影响主流程，仅记录警告日志
                }
                
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("完成维修工单失败，工单ID: {}, 错误: {}", orderId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    @GlobalTransactional
    public boolean cancelRepairOrder(Long orderId, String reason) {
        try {
            // 参数验证
            if (orderId == null) {
                log.warn("取消维修工单失败，工单ID不能为空");
                return false;
            }

            log.info("取消维修工单，工单ID: {}, 原因: {}", orderId, reason);

            // 数据权限验证
            if (!validateRepairOrderPermission(orderId)) {
                log.warn("用户无权限取消维修工单，工单ID: {}", orderId);
                return false;
            }

            // 获取工单信息
            RepairOrder repairOrder = getById(orderId);
            if (repairOrder == null) {
                log.warn("工单不存在，工单ID: {}", orderId);
                return false;
            }

            int result = repairOrderMapper.cancelOrder(orderId, SecurityUtils.getCurrentUserId());
            if (result > 0) {
                log.info("维修工单取消成功，工单ID: {}", orderId);
                
                // 创建工单取消进度记录
                try {
                    String operatorName = getCurrentUserName();
                    createStatusProgressRecord(orderId, repairOrder.getOrderNo(), 5, "取消原因：" + reason, operatorName);
                } catch (Exception e) {
                    log.warn("创建工单取消进度记录失败，工单ID: {}", orderId, e);
                    // 不影响主流程，仅记录警告日志
                }
                
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("取消维修工单失败，工单ID: {}, 错误: {}", orderId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    @GlobalTransactional
    public boolean submitRating(Long orderId, Integer satisfaction) {
        try {
            // 参数验证
            if (orderId == null || satisfaction == null) {
                log.warn("提交满意度评分失败，工单ID或满意度不能为空");
                return false;
            }

            log.info("提交满意度评分，工单ID: {}, 评分: {}", orderId, satisfaction);

            // 数据权限验证
            if (!validateRepairOrderPermission(orderId)) {
                log.warn("用户无权限提交满意度评分，工单ID: {}", orderId);
                return false;
            }

            // 获取工单信息
            RepairOrder repairOrder = getById(orderId);
            if (repairOrder == null) {
                log.warn("工单不存在，工单ID: {}", orderId);
                return false;
            }

            // 验证工单状态，只有已完成的工单才能评分
            if (repairOrder.getStatus() != 4) {
                log.warn("工单状态不正确，无法评分，工单ID: {}, 状态: {}", orderId, repairOrder.getStatus());
                return false;
            }

            // 验证是否已经评分
            if (repairOrder.getSatisfaction() != null && repairOrder.getSatisfaction() > 0) {
                log.warn("工单已经评分，不能重复评分，工单ID: {}", orderId);
                return false;
            }

            // 更新满意度评分
            int result = repairOrderMapper.updateSatisfaction(orderId, satisfaction, SecurityUtils.getCurrentUserId());
            if (result > 0) {
                log.info("满意度评分提交成功，工单ID: {}, 评分: {}", orderId, satisfaction);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("提交满意度评分失败，工单ID: {}, 错误: {}", orderId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    @Cacheable(value = "repair:byUserId", key = "#userId + ':' + #communityId + ':' + #status", unless = "#result == null || #result.isEmpty()")
    public List<RepairOrderVO> getRepairOrdersByUserId(Long userId, Long communityId, Integer status) {
        try {
            // 参数验证
            if (userId == null) {
                log.warn("根据用户ID查询维修工单失败，用户ID不能为空");
                return Collections.emptyList();
            }

            log.info("根据用户ID查询维修工单，用户ID: {}, 社区ID: {}, 状态: {}", userId, communityId, status);

            List<RepairOrder> repairOrders = repairOrderMapper.selectByUserId(userId, communityId, status);
            return convertToRepairOrderVOList(repairOrders);
        } catch (Exception e) {
            log.error("根据用户ID查询维修工单失败，用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    @Cacheable(value = "repair:byRepairmanId", key = "#repairmanId + ':' + #communityId + ':' + #status", unless = "#result == null || #result.isEmpty()")
    public List<RepairOrderVO> getRepairOrdersByRepairmanId(Long repairmanId, Long communityId, Integer status) {
        try {
            // 参数验证
            if (repairmanId == null) {
                log.warn("根据维修人员ID查询维修工单失败，维修人员ID不能为空");
                return Collections.emptyList();
            }

            log.info("根据维修人员ID查询维修工单，维修人员ID: {}, 社区ID: {}, 状态: {}", repairmanId, communityId, status);

            List<RepairOrder> repairOrders = repairOrderMapper.selectByAssignTo(repairmanId, communityId, status);
            return convertToRepairOrderVOList(repairOrders);
        } catch (Exception e) {
            log.error("根据维修人员ID查询维修工单失败，维修人员ID: {}, 错误: {}", repairmanId, e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    @Cacheable(value = "repair:urgent", key = "#communityId", unless = "#result == null || #result.isEmpty()")
    public List<RepairOrderVO> getUrgentRepairOrders(Long communityId) {
        try {
            log.info("查询紧急维修工单，社区ID: {}", communityId);

            List<RepairOrder> repairOrders = repairOrderMapper.selectUrgentPendingOrders(communityId);
            return convertToRepairOrderVOList(repairOrders);
        } catch (Exception e) {
            log.error("查询紧急维修工单失败，社区ID: {}, 错误: {}", communityId, e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    @Cacheable(value = "repair:timeout", key = "#communityId + ':' + #timeoutHours", unless = "#result == null || #result.isEmpty()")
    public List<RepairOrderVO> getTimeoutRepairOrders(Long communityId, Integer timeoutHours) {
        try {
            if (timeoutHours == null) {
                timeoutHours = 24; // 默认24小时
            }

            log.info("查询超时维修工单，社区ID: {}, 超时小时数: {}", communityId, timeoutHours);

            List<RepairOrder> repairOrders = repairOrderMapper.selectTimeoutOrders(communityId, timeoutHours);
            return convertToRepairOrderVOList(repairOrders);
        } catch (Exception e) {
            log.error("查询超时维修工单失败，社区ID: {}, 错误: {}", communityId, e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    @Override
    @Cacheable(value = "repair:statistics", key = "#communityId + ':' + #startDate + ':' + #endDate", unless = "#result == null")
    public RepairOrderStatisticsVO getRepairOrderStatistics(Long communityId, LocalDate startDate, LocalDate endDate) {
        try {
            log.info("获取维修工单统计信息，社区ID: {}, 开始日期: {}, 结束日期: {}", communityId, startDate, endDate);

            // 统计区间暂不参与SQL，留作后续扩展

            // 获取各状态工单数量
            List<Map<String, Object>> statusStats = repairOrderMapper.selectStatusStatistics(communityId);
            Map<String, Integer> statusMap = new HashMap<>();
            for (Map<String, Object> stat : statusStats) {
                String statusName = (String) stat.get("status_name");
                Integer count = (Integer) stat.get("count");
                if (statusName != null && count != null) {
                    statusMap.put(statusName, count);
                }
            }

            // 获取各类型工单数量（简化处理）
            Map<String, Integer> typeMap = new HashMap<>();
            typeMap.put("水电", 0);
            typeMap.put("门窗", 0);
            typeMap.put("电梯", 0);
            typeMap.put("空调", 0);
            typeMap.put("其他", 0);

            // 获取各紧急程度工单数量（简化处理）
            Map<String, Integer> urgencyMap = new HashMap<>();
            urgencyMap.put("一般", 0);
            urgencyMap.put("紧急", 0);
            urgencyMap.put("非常紧急", 0);

            RepairOrderStatisticsVO statistics = new RepairOrderStatisticsVO();
            statistics.setCommunityId(communityId);
            statistics.setStartDate(startDate);
            statistics.setEndDate(endDate);
            statistics.setTotalOrders(statusMap.values().stream().mapToInt(Integer::intValue).sum());
            statistics.setCompletedOrders(statusMap.getOrDefault("已完成", 0));
            statistics.setCancelledOrders(statusMap.getOrDefault("已取消", 0));
            statistics.setPendingOrders(statusMap.getOrDefault("待处理", 0));
            statistics.setProcessingOrders(statusMap.getOrDefault("处理中", 0));
            // 移除不存在的方法调用
            // statistics.setStatusDistribution(statusMap);
            // statistics.setTypeDistribution(typeMap);
            // statistics.setUrgencyDistribution(urgencyMap);
            statistics.setAverageProcessingTime(calculateAverageProcessingTime(communityId));
            statistics.setOnTimeCompletionRate(calculateOnTimeCompletionRate(communityId));

            return statistics;
        } catch (Exception e) {
            log.error("获取维修工单统计信息失败，错误: {}", e.getMessage(), e);
            return new RepairOrderStatisticsVO();
        }
    }

    @Override
    public String generateOrderNo() {
        try {
            // 新规则：RO{年月日时分秒}{随机6位时间戳}
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            String randomSuffix = String.format("%06d", new Random().nextInt(999999));
            String orderNo = "RO" + timestamp + randomSuffix;
            
            log.info("生成维修工单号: {}", orderNo);
            return orderNo;
        } catch (Exception e) {
            log.error("生成工单号失败，错误: {}", e.getMessage(), e);
            // 备用方案：使用当前时间戳
            return "RO" + System.currentTimeMillis();
        }
    }

    // ========================= 私有方法 =========================

    /**
     * 获取当前用户名
     * @return 当前用户名，如果获取失败则返回"系统用户"
     */
    private String getCurrentUserName() {
        try {
            Long currentUserId = SecurityUtils.getCurrentUserId();
            if (currentUserId == null) {
                log.warn("获取当前用户ID失败");
                return "系统用户";
            }
            
            // 获取用户信息
            UserDTO userDTO = getUserById(currentUserId);
            if (userDTO != null) {
                return StringUtils.hasText(userDTO.getRealName()) ? userDTO.getRealName() : userDTO.getUsername();
            } else {
                log.warn("获取当前用户信息失败，用户ID: {}, 用户信息为空", currentUserId);
                return "系统用户";
            }
        } catch (Exception e) {
            log.warn("调用用户服务获取当前用户信息异常，用户ID: {}", SecurityUtils.getCurrentUserId(), e);
            return "系统用户";
        }
    }

    /**
     * 转换为RepairOrderVO
     */
    private RepairOrderVO convertToRepairOrderVO(RepairOrder repairOrder) {
        if (repairOrder == null) {
            return null;
        }

        RepairOrderVO vo = new RepairOrderVO();
        BeanUtils.copyProperties(repairOrder, vo);
        return vo;
    }

    /**
     * 转换为RepairOrderVO列表
     */
    private List<RepairOrderVO> convertToRepairOrderVOList(List<RepairOrder> repairOrders) {
        if (repairOrders == null || repairOrders.isEmpty()) {
            return Collections.emptyList();
        }

        return repairOrders.stream()
                .map(this::convertToRepairOrderVO)
                .collect(Collectors.toList());
    }

    /**
     * 创建状态变更进度记录
     */
    private void createStatusProgressRecord(Long orderId, String orderNo, Integer status, String remark, String operatorName) {
        try {
            String progressTitle;
            String progressContent;
            // 进度时间由进度服务内部生成，此处不单独使用

            switch (status) {
                case 3: // 开始维修
                    progressTitle = "开始维修";
                    progressContent = "开始维修";
                    break;
                case 4: // 已完成
                    progressTitle = "维修完成";
                    progressContent = "工单已完成";
                    break;
                case 5: // 已取消
                    progressTitle = "工单取消";
                    progressContent = "工单已取消";
                    break;
                default:
                    progressTitle = "状态更新";
                    progressContent = "工单状态已更新";
                    break;
            }

            if (remark != null && !remark.trim().isEmpty()) {
                progressContent += "，备注：" + remark;
            }

            repairProgressService.createProgress(
                orderId,
                orderNo,
                status,
                progressTitle,
                progressContent,
                SecurityUtils.getCurrentUserId(),
                operatorName
            );
        } catch (Exception e) {
            log.warn("创建状态变更进度记录失败，工单ID: {}, 状态: {}", orderId, status, e);
        }
    }

    /**
     * 计算平均处理时间
     * @param communityId 社区ID
     * @return 平均处理时间（小时），如果无法计算则返回0
     */
    private BigDecimal calculateAverageProcessingTime(Long communityId) {
        try {
            // 使用现有的查询方法获取已完成的工单
            List<RepairOrder> completedOrders = repairOrderMapper.selectByAssignTo(null, communityId, 4); // 状态4表示已完成
            if (completedOrders == null || completedOrders.isEmpty()) {
                return BigDecimal.ZERO;
            }
            
            long totalProcessingTime = 0;
            int validOrderCount = 0;
            
            for (RepairOrder order : completedOrders) {
                if (order.getCreateTime() != null && order.getCompleteTime() != null) {
                    long processingTime = java.time.Duration.between(order.getCreateTime(), order.getCompleteTime()).toHours();
                    totalProcessingTime += processingTime;
                    validOrderCount++;
                }
            }
            
            if (validOrderCount == 0) {
                return BigDecimal.ZERO;
            }
            
            return BigDecimal.valueOf(totalProcessingTime).divide(BigDecimal.valueOf(validOrderCount), 2, BigDecimal.ROUND_HALF_UP);
        } catch (Exception e) {
            log.warn("计算平均处理时间失败，社区ID: {}", communityId, e);
            return BigDecimal.ZERO;
        }
    }

    /**
     * 计算按时完成率
     * @param communityId 社区ID
     * @return 按时完成率（百分比），如果无法计算则返回0
     */
    private BigDecimal calculateOnTimeCompletionRate(Long communityId) {
        try {
            // 使用现有的查询方法获取已完成的工单
            List<RepairOrder> completedOrders = repairOrderMapper.selectByAssignTo(null, communityId, 4); // 状态4表示已完成
            if (completedOrders == null || completedOrders.isEmpty()) {
                return BigDecimal.ZERO;
            }
            
            int onTimeCount = 0;
            int totalCount = 0;
            
            for (RepairOrder order : completedOrders) {
                if (order.getCreateTime() != null && order.getCompleteTime() != null) {
                    totalCount++;
                    // 假设标准处理时间为72小时（3天）
                    long processingTime = java.time.Duration.between(order.getCreateTime(), order.getCompleteTime()).toHours();
                    if (processingTime <= 72) {
                        onTimeCount++;
                    }
                }
            }
            
            if (totalCount == 0) {
                return BigDecimal.ZERO;
            }
            
            return BigDecimal.valueOf(onTimeCount)
                    .multiply(BigDecimal.valueOf(100))
                    .divide(BigDecimal.valueOf(totalCount), 2, BigDecimal.ROUND_HALF_UP);
        } catch (Exception e) {
            log.warn("计算按时完成率失败，社区ID: {}", communityId, e);
            return BigDecimal.ZERO;
        }
    }

    /**
     * 根据维修人员ID获取维修人员姓名
     * @param repairmanId 维修人员ID
     * @return 维修人员姓名，如果获取失败则返回"未知维修人员"
     */
    private String getRepairmanName(Long repairmanId) {
        if (repairmanId == null) {
            return "未分配";
        }
        
        try {
            // 获取用户信息
            UserDTO userDTO = getUserById(repairmanId);
            if (userDTO != null) {
                return StringUtils.hasText(userDTO.getRealName()) ? userDTO.getRealName() : userDTO.getUsername();
            } else {
                log.warn("获取维修人员信息失败，维修人员ID: {}, 用户信息为空", repairmanId);
                return "未知维修人员";
            }
        } catch (Exception e) {
            log.warn("调用用户服务获取维修人员信息异常，维修人员ID: {}", repairmanId, e);
            return "未知维修人员";
        }
    }

    @Override
    @GlobalTransactional
    @CacheEvict(value = {"repair:detail", "repair:myOrders", "repair:byUserId", "repair:byRepairmanId", "repair:urgent", "repair:timeout", "repair:statistics"}, allEntries = true)
    public boolean updateLatestProgressContent(Long orderId, String progressContent) {
        try {
            // 参数验证
            if (orderId == null || !StringUtils.hasText(progressContent)) {
                log.warn("更新最新进度记录内容参数不完整，工单ID: {}, 进度内容: {}", orderId, progressContent);
                return false;
            }

            // 数据权限验证
            if (!validateRepairOrderPermission(orderId)) {
                log.warn("用户无权限更新维修工单进度记录，工单ID: {}", orderId);
                return false;
            }

            // 调用进度服务更新最新进度记录的内容
            return repairProgressService.updateProgressContent(orderId, progressContent);
        } catch (Exception e) {
            log.error("更新最新进度记录内容异常，工单ID: {}, 错误: {}", orderId, e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 保存维修工单图片
     * 
     * 按照《用户上传文件功能使用指南.md》规范，将图片URL列表转换为标准的JSON格式文件信息
     * 使用FileInfoUtils工具类确保格式一致性
     * 
     * @param orderId 工单ID
     * @param imageList 图片URL列表
     */
    private void saveRepairOrderImages(Long orderId, List<String> imageList) {
        try {
            if (orderId == null || imageList == null || imageList.isEmpty()) {
                log.warn("保存维修工单图片参数无效，工单ID: {}, 图片数量: {}", 
                        orderId, imageList != null ? imageList.size() : 0);
                return;
            }
            
            // 将图片URL列表转换为标准的文件信息格式
            List<com.smart.community.commons.dto.FileInfoDTO> fileInfoList = new ArrayList<>();
            for (int i = 0; i < imageList.size(); i++) {
                String imageUrl = imageList.get(i);
                if (StringUtils.hasText(imageUrl)) {
                    com.smart.community.commons.dto.FileInfoDTO fileInfo = new com.smart.community.commons.dto.FileInfoDTO();
                    fileInfo.setId("repair_image_" + orderId + "_" + System.currentTimeMillis() + "_" + i);
                    fileInfo.setFileName(extractFileNameFromUrl(imageUrl));
                    fileInfo.setFileUrl(imageUrl);
                    fileInfo.setFileSize(0L);
                    fileInfo.setUploadType("REPAIR_IMAGE");
                    fileInfo.setUploadSource("APP");
                    fileInfo.setStatus("success");
                    fileInfo.setCreateTime(LocalDateTime.now().toString());
                    fileInfo.setFileType("image/jpeg");
                    fileInfo.setFileExtension("jpg");
                    fileInfo.setOriginalFileName(extractFileNameFromUrl(imageUrl));
                    fileInfo.setFilePath(imageUrl);
                    
                    fileInfoList.add(fileInfo);
                }
            }
            
            // 使用FileInfoUtils工具类转换为JSON字符串
            String repairImagesJson = com.smart.community.commons.utils.FileInfoUtils.toJsonString(fileInfoList);
            
            // 更新工单的图片字段
            RepairOrder updateOrder = new RepairOrder();
            updateOrder.setId(orderId);
            updateOrder.setRepairImages(repairImagesJson);
            updateOrder.setUpdateTime(LocalDateTime.now());
            
            int updateResult = repairOrderMapper.updateById(updateOrder);
            if (updateResult > 0) {
                log.info("维修工单图片保存成功，工单ID: {}, 图片数量: {}, JSON格式: {}", 
                        orderId, imageList.size(), repairImagesJson);
            } else {
                log.warn("维修工单图片保存失败，工单ID: {}", orderId);
            }
        } catch (Exception e) {
            log.warn("保存维修工单图片异常，工单ID: {}", orderId, e);
            throw new RuntimeException("保存维修工单图片失败", e);
        }
    }

    /**
     * 从URL中提取文件名
     * @param url URL
     * @return 文件名
     */
    private String extractFileNameFromUrl(String url) {
        if (StringUtils.hasText(url)) {
            String[] parts = url.split("/");
            return parts[parts.length - 1];
        }
        return "unknown_file";
    }
    
    // ========================= 辅助方法 =========================
    
    /**
     * 获取当前用户数据权限范围
     * @return 数据权限信息
     */
    private DataScopeInfo getCurrentUserDataScope() {
        try {
            return dataScopeService.getCurrentUserDataScope();
        } catch (Exception e) {
            log.warn("获取当前用户数据权限信息失败，可能是Feign接口调用或用户未登录: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * 验证维修工单权限
     * @param orderId 工单ID
     * @return 是否有权限
     */
    private boolean validateRepairOrderPermission(Long orderId) {
        try {
            // 获取当前用户数据权限范围
            DataScopeInfo dataScope = getCurrentUserDataScope();
            if (dataScope == null) {
                return false;
            }
            
            // 超级管理员有所有权限
            if (dataScope.isSuperAdmin()) {
                return true;
            }
            
            // 获取工单信息
            RepairOrder repairOrder = getById(orderId);
            if (repairOrder == null) {
                return false;
            }
            
            Long currentUserId = SecurityUtils.getCurrentUserId();
            if (currentUserId == null) {
                return false;
            }
            
            // 物业公司用户：检查是否有权限访问该社区的工单
            if (dataScope.isPropertyCompanyUser()) {
                List<Long> userCommunityIds = dataScope.getCommunityIds();
                return userCommunityIds != null && userCommunityIds.contains(repairOrder.getCommunityId());
            }
            
            // 普通用户：只能访问自己申请的工单
            return repairOrder.getUserId().equals(currentUserId);
        } catch (Exception e) {
            log.warn("验证维修工单权限失败，工单ID: {}, 错误: {}", orderId, e.getMessage());
            return false;
        }
    }
    
    /**
     * 获取用户信息
     * @param userId 用户ID
     * @return 用户信息
     */
    private UserDTO getUserById(Long userId) {
        if (userId == null) {
            return null;
        }
        
        try {
            // 调用Feign服务获取用户信息
            UserDTO userDTO = userFeignService.getUserById(userId);
            if (userDTO != null) {
                // 更新本地缓存
                userCache.put(userId, userDTO);
                return userDTO;
            }
        } catch (Exception e) {
            log.warn("调用用户服务获取用户信息失败，用户ID: {}, 错误: {}", userId, e.getMessage());
        }
        
        return null;
    }
    
    /**
     * 获取地址信息
     * @param householdId 房户ID
     * @return 地址信息
     */
    private AddressInfoDTO getAddressByHouseholdId(Long householdId) {
        if (householdId == null) {
            return null;
        }
        
        try {
            // 调用Feign服务获取地址信息
            AddressInfoDTO addressDTO = regionAddressFeignService.getAddressByHouseholdId(householdId);
            if (addressDTO != null) {
                // 更新本地缓存
                addressCache.put(householdId, addressDTO);
                return addressDTO;
            }
        } catch (Exception e) {
            log.warn("调用地址服务获取地址信息失败，房户ID: {}, 错误: {}", householdId, e.getMessage());
        }
        
        return null;
    }
    
    // ========================= 移动端维修工单管理 =========================
    
    @Override
    public Map<String, Object> getMobileRepairOrderStatistics(Long userId, List<Long> communityIds) throws Exception {
        if (userId == null) {
            log.warn("获取移动端维修工单统计概览失败，用户ID为空");
            throw new IllegalArgumentException("用户ID不能为空");
        }
        if (communityIds == null || communityIds.isEmpty()) {
            log.warn("获取移动端维修工单统计概览失败，社区ID列表为空，用户ID: {}", userId);
            throw new IllegalArgumentException("社区ID列表不能为空");
        }
        
        log.info("开始获取移动端维修工单统计概览，用户ID: {}, 社区数量: {}", userId, communityIds.size());
        
        try {
            // 构建查询条件
            LambdaQueryWrapper<RepairOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(RepairOrder::getCommunityId, communityIds);
            wrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            
            // 统计待处理工单（状态为1）
            LambdaQueryWrapper<RepairOrder> pendingWrapper = new LambdaQueryWrapper<>();
            pendingWrapper.in(RepairOrder::getCommunityId, communityIds);
            pendingWrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            pendingWrapper.eq(RepairOrder::getStatus, 1);
            long pendingCount = count(pendingWrapper);
            
            // 统计进行中工单（状态为2和3）
            LambdaQueryWrapper<RepairOrder> inProgressWrapper = new LambdaQueryWrapper<>();
            inProgressWrapper.in(RepairOrder::getCommunityId, communityIds);
            inProgressWrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            inProgressWrapper.in(RepairOrder::getStatus, 2, 3);
            long inProgressCount = count(inProgressWrapper);
            
            // 统计已完成工单（状态为4）
            LambdaQueryWrapper<RepairOrder> completedWrapper = new LambdaQueryWrapper<>();
            completedWrapper.in(RepairOrder::getCommunityId, communityIds);
            completedWrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            completedWrapper.eq(RepairOrder::getStatus, 4);
            long completedCount = count(completedWrapper);
            
            // 统计紧急工单（紧急程度为1）
            LambdaQueryWrapper<RepairOrder> urgentWrapper = new LambdaQueryWrapper<>();
            urgentWrapper.in(RepairOrder::getCommunityId, communityIds);
            urgentWrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            urgentWrapper.eq(RepairOrder::getUrgencyLevel, 1);
            long urgentCount = count(urgentWrapper);
            
            // 构建统计结果
            Map<String, Object> statistics = new HashMap<>();
            statistics.put("pendingCount", pendingCount);
            statistics.put("inProgressCount", inProgressCount);
            statistics.put("completedCount", completedCount);
            statistics.put("urgentCount", urgentCount);
            
            log.info("获取移动端维修工单统计概览成功，用户ID: {}, 待处理: {}, 进行中: {}, 已完成: {}, 紧急: {}", 
                    userId, pendingCount, inProgressCount, completedCount, urgentCount);
            
            return statistics;
            
        } catch (Exception e) {
            log.error("获取移动端维修工单统计概览失败，用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            throw e;
        }
    }
    
    @Override
    public Map<String, Object> getPendingAssignmentOrders(Integer current, Integer size, List<Long> communityIds) throws Exception {
        if (communityIds == null || communityIds.isEmpty()) {
            log.warn("获取待分配工单列表失败，社区ID列表为空");
            throw new IllegalArgumentException("社区ID列表不能为空");
        }
        
        // 分页参数验证
        if (current == null || current < 1) {
            current = 1;
        }
        if (size == null || size < 1 || size > 100) {
            size = 10;
        }
        
        log.info("开始获取待分配工单列表，当前页: {}, 每页大小: {}, 社区数量: {}", current, size, communityIds.size());
        
        try {
            // 构建查询条件：状态为1（待受理）的工单
            LambdaQueryWrapper<RepairOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(RepairOrder::getCommunityId, communityIds);
            wrapper.eq(RepairOrder::getStatus, 1); // 待受理
            wrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            wrapper.orderByDesc(RepairOrder::getCreateTime);
            
            // 分页查询
            Page<RepairOrder> page = new Page<>(current, size);
            IPage<RepairOrder> pageResult = page(page, wrapper);
            
            // 转换为VO
            List<RepairOrderVO> records = pageResult.getRecords().stream()
                    .map(this::convertToRepairOrderVO)
                    .collect(Collectors.toList());
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("records", records);
            result.put("total", pageResult.getTotal());
            result.put("current", pageResult.getCurrent());
            result.put("size", pageResult.getSize());
            result.put("pages", pageResult.getPages());
            
            log.info("获取待分配工单列表成功，总记录数: {}, 当前页记录数: {}, 总页数: {}", 
                    pageResult.getTotal(), records.size(), pageResult.getPages());
            
            return result;
            
        } catch (Exception e) {
            log.error("获取待分配工单列表失败，错误: {}", e.getMessage(), e);
            throw e;
        }
    }
    
    @Override
    public Map<String, Object> getMyOrders(Long userId, Integer current, Integer size, Integer status) throws Exception {
        if (userId == null) {
            log.warn("获取我的工单列表失败，用户ID为空");
            throw new IllegalArgumentException("用户ID不能为空");
        }
        
        // 分页参数验证
        if (current == null || current < 1) {
            current = 1;
        }
        if (size == null || size < 1 || size > 100) {
            size = 10;
        }
        
        log.info("开始获取我的工单列表，用户ID: {}, 状态: {}, 当前页: {}, 每页大小: {}", 
                userId, status, current, size);
        
        try {
            // 构建查询条件：分配给当前用户的工单
            LambdaQueryWrapper<RepairOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RepairOrder::getAssignTo, userId);
            wrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            
            // 状态筛选
            if (status != null) {
                wrapper.eq(RepairOrder::getStatus, status);
            }
            
            wrapper.orderByDesc(RepairOrder::getCreateTime);
            
            // 分页查询
            Page<RepairOrder> page = new Page<>(current, size);
            IPage<RepairOrder> pageResult = page(page, wrapper);
            
            // 转换为VO
            List<RepairOrderVO> records = pageResult.getRecords().stream()
                    .map(this::convertToRepairOrderVO)
                    .collect(Collectors.toList());
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("records", records);
            result.put("total", pageResult.getTotal());
            result.put("current", pageResult.getCurrent());
            result.put("size", pageResult.getSize());
            result.put("pages", pageResult.getPages());
            
            log.info("获取我的工单列表成功，用户ID: {}, 总记录数: {}, 当前页记录数: {}, 总页数: {}", 
                    userId, pageResult.getTotal(), records.size(), pageResult.getPages());
            
            return result;
            
        } catch (Exception e) {
            log.error("获取我的工单列表失败，用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            throw e;
        }
    }

    // ==================== 房户详情Tab页方法实现 ====================

    @Override
    @Cacheable(value = "repair:household", key = "#householdId + ':' + #current + ':' + #size", unless = "#result == null || #result.getRecords().isEmpty()")
    public PageResult<RepairOrderVO> getHouseholdRepairOrders(Long householdId, Integer current, Integer size) throws Exception {
        log.info("获取房户报修列表，房户ID：{}，当前页：{}，每页大小：{}", householdId, current, size);
        
        try {
            // 1. 根据房户ID获取所有关联的用户ID
            List<Long> userIds = regionDataFeignService.getUserIdsByHouseholdId(householdId);
            
            if (userIds.isEmpty()) {
                log.info("房户ID：{} 没有关联的用户", householdId);
                return PageResult.of(current, size, 0L, new ArrayList<>());
            }
            
            // 2. 根据用户ID列表查询报修工单
            LambdaQueryWrapper<RepairOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(RepairOrder::getUserId, userIds);
            wrapper.eq(RepairOrder::getDeleted, SystemStatusEnum.NOT_DELETED.getCode());
            wrapper.orderByDesc(RepairOrder::getCreateTime);
            
            // 3. 分页查询
            Page<RepairOrder> page = new Page<>(current, size);
            IPage<RepairOrder> pageResult = page(page, wrapper);
            
            // 4. 转换为VO
            List<RepairOrderVO> records = pageResult.getRecords().stream()
                    .map(this::convertToRepairOrderVO)
                    .collect(Collectors.toList());
            
            // 5. 构建分页结果
            PageResult<RepairOrderVO> result = PageResult.of(
                    current, 
                    size, 
                    pageResult.getTotal(), 
                    records
            );
            
            log.info("获取房户报修列表成功，房户ID：{}，报修数量：{}", householdId, pageResult.getTotal());
            return result;
            
        } catch (Exception e) {
            log.error("获取房户报修列表失败，房户ID：{}", householdId, e);
            throw new Exception("获取房户报修列表失败：" + e.getMessage());
        }
    }
    
} 
